﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace NORM.Common
{
    /// <summary>
    /// 描述：转换辅助
    /// 作者：王晓东
    /// 更新时间：2014-04-23
    /// </summary>
    internal class ConvertTo
    {
        private static PropertyInfo GetProperty(string name,Type type)
        {
            //return CacheProperties.cacheInstance.GetProperty(type, name);
            return type.GetProperty(name);  //BindingFlags.Instance | BindingFlags.Public        
        }

        /// <summary>
        /// 表转换成泛型集合
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="Source">数据源</param>
        /// <returns></returns>
        public static List<T> ConvertToList<T>(System.Data.DataTable Source)
        {
            List<T> dlist = new List<T>();
            Type type = typeof(T);
            FieldInfo[] fields = type.GetFields();
            foreach (System.Data.DataRow dr in Source.Rows)
            {
                T O = (T)Activator.CreateInstance(typeof(T));// new T();
                foreach (System.Data.DataColumn dc in Source.Columns)
                {
                    string columnName = dc.ColumnName;
                    columnName = columnName.Replace("[", "").Replace("]", "").Trim();

                    PropertyInfo pi = type.GetProperty(columnName);
                    if (pi != null)
                    {
                        Type _type = pi.PropertyType;

                        var d_value = dr[dc.ColumnName];

                        if (d_value != null && d_value != DBNull.Value)
                        {
                            switch (_type.Name)
                            {
                                case "Guid": pi.SetValue(O, (Guid)dr[dc.ColumnName], null); break;
                                case "Int16": pi.SetValue(O, Int16.Parse(dr[dc.ColumnName] + ""), null); break;
                                case "Int32": pi.SetValue(O, Int32.Parse(dr[dc.ColumnName] + ""), null); break;
                                case "Int64": pi.SetValue(O, Int64.Parse(dr[dc.ColumnName] + ""), null); break;                              
                                case "Decimal": pi.SetValue(O, Decimal.Parse(dr[dc.ColumnName] + ""), null); break;
                                case "Boolean": pi.SetValue(O, Boolean.Parse(dr[dc.ColumnName] + ""), null); break;
                                case "Double": pi.SetValue(O, Double.Parse(dr[dc.ColumnName] + ""), null); break;
                                case "Byte[]": pi.SetValue(O, (Byte[])dr[dc.ColumnName], null); break;
                                case "String": pi.SetValue(O, dr[dc.ColumnName] + "", null); break;
                                case "Char": pi.SetValue(O, Char.Parse(dr[dc.ColumnName] + ""), null); break;
                                default: pi.SetValue(O, dr[dc.ColumnName], null); break;
                            }
                        }
                    }

                }
                dlist.Add(O);
            }
            return dlist;
        }

        /// <summary>
        /// 表转换成泛型集合
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="Source">数据源</param>
        /// <param name="InitItem">初始化项</param>
        /// <returns></returns>
        public static List<T> ConvertToList<T>(System.Data.DataTable Source, T InitItem)
        {
            List<T> dlist = new List<T>();
            dlist.Add(InitItem);

            Type type = typeof(T);
            foreach (System.Data.DataRow dr in Source.Rows)
            {
                T O = (T)Activator.CreateInstance(typeof(T));// new T();
                foreach (System.Data.DataColumn dc in Source.Columns)
                {
                    type.GetProperty(dc.ColumnName).SetValue(O, dr[dc.ColumnName], null);
                }
                dlist.Add(O);
            }
            return dlist;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Source"></param>
        /// <returns></returns>
        public static List<T> ConvertToList<T>(System.Data.Common.DbDataReader Source)
        {
            List<T> dlist = new List<T>();

            Type _type = typeof(T);

            #region 之前代码

            //System.Data.DataTable dt = Source.GetSchemaTable();
            //while (Source.Read())
            //{
            //    T O = Activator.CreateInstance<T>();
            //    foreach (System.Data.DataRow dr in dt.Rows)
            //    {
            //        string columnName = dr["ColumnName"] + "";
            //        string columnType = dr["DataType"] + "";
            //        var pi = _type.GetProperty(columnName);
            //        if (pi != null)
            //        {
            //            var d_value = Source[columnName];
            //            if (d_value != null && d_value != DBNull.Value)
            //            {
            //                switch (columnType)
            //                {
            //                    case "System.Guid": pi.SetValue(O, (Guid)d_value, null); break;
            //                    case "System.Int16": pi.SetValue(O, Int16.Parse(d_value.ToString()), null); break;
            //                    case "System.Int32": pi.SetValue(O, Int32.Parse(d_value.ToString()), null); break;
            //                    case "System.Int64": pi.SetValue(O, Int64.Parse(d_value.ToString()), null); break;
            //                    case "System.Decimal": pi.SetValue(O, Decimal.Parse(d_value.ToString()), null); break;
            //                    case "System.Boolean": pi.SetValue(O, Boolean.Parse(d_value.ToString()), null); break;
            //                    case "System.Double": pi.SetValue(O, Double.Parse(d_value.ToString()), null); break;
            //                    case "Byte[]": pi.SetValue(O, (Byte[])d_value, null); break;
            //                    case "System.Byte[]": pi.SetValue(O, (Byte[])d_value, null); break;
            //                    case "System.String": pi.SetValue(O, d_value + "", null); break;
            //                    case "System.Char": pi.SetValue(O, Char.Parse(d_value.ToString()), null); break;
            //                    default: pi.SetValue(O, d_value, null); break;
            //                }
            //            }
            //        }
            //    }
            //    dlist.Add(O);
            //}

            //dt.Dispose(); 

            #endregion
            
            #region 最新代码

            while (Source.Read())
            {

                T O = Activator.CreateInstance<T>();

                for (int i = 0; i < Source.FieldCount; i++)
                {
                    string columnName = Source.GetName(i);
                    string columnType = Source.GetFieldType(i).Name;
                    var pi = GetProperty(columnName, _type); //_type.GetProperty(columnName);
                    if (pi != null)
                    {
                        var d_value = Source[columnName];
                        if (d_value != null && d_value != DBNull.Value)
                        {
                            switch (columnType)
                            {
                                case "Guid": pi.SetValue(O, (Guid)d_value, null); break;
                                case "Int16": pi.SetValue(O, Int16.Parse(d_value.ToString()), null); break;
                                case "Int32": pi.SetValue(O, Int32.Parse(d_value.ToString()), null); break;
                                case "Int64": pi.SetValue(O, Int64.Parse(d_value.ToString()), null); break;
                                case "Decimal": pi.SetValue(O, Decimal.Parse(d_value.ToString()), null); break;
                                case "Boolean": pi.SetValue(O, Boolean.Parse(d_value.ToString()), null); break;
                                case "Double": pi.SetValue(O, Double.Parse(d_value.ToString()), null); break;
                                case "Byte[]": pi.SetValue(O, (Byte[])d_value, null); break;
                                case "String": pi.SetValue(O, d_value + "", null); break;
                                case "Char": pi.SetValue(O, Char.Parse(d_value.ToString()), null); break;
                                default: pi.SetValue(O, d_value, null); break;
                            }
                        }
                    }

                }

                dlist.Add(O);

            }          

            #endregion

            return dlist;
        } 

    }
}
